#===============================================
# Code written by Joe France (joeprogram.com)
# Released under code.google.com/p/video-scholar/
# with the MIT license (aka, the do-whatever-you-want-with-it license)
#===============================================

import pyglet
from pyglet.window import key
from CompoundGUI import CompoundGUI
from GUI import GUI

class VideoPlayer( CompoundGUI ):
	'''
	The Video Player contains GUI controls for the pyglet Player object
	It makes sure the video is the right size on the screen,
	and can handle things like play/pause
	'''
	
	WIDTH = 550
	HEIGHT = 366
	
	PLAY = "play"
	PAUSE = "pause"
	
	def __init__( self, video_path ):
	
		super( VideoPlayer, self).__init__()
	
		self.video = pyglet.media.load(video_path)
	
		self.player = pyglet.media.Player()
		self.player.queue( self.video )
		self.player.eos_action = self.player.EOS_PAUSE
		
		# This is a stack of what the video player should be doing
		# The video player will respond to the last action in the stack
		# This way we can temporarily pause the player when it is being dragged or a file is saved
		# and it will return to its previous action when we're done
		# The bottom of the stack is the 'base'
		# and is treated specially
		self.actions = [ self.PLAY ] 
		self.do_action()

		self.set_coordinates( 25, 90 )
		self.set_dimensions( self.WIDTH, self.HEIGHT )
		
		self.play_button = GUI( 'play_button.png', origin = "center center")
		self.play_button.set_coordinates( self.x + self.WIDTH/2, self.y + self.HEIGHT/2 )

		# Sets the base action to pause 
		# When the video reaches the end of its stream
		@self.player.event
		def on_eos():
			self.set_base_action( self.PAUSE )

	
	def get_duration( self ):
		return self.video.duration
		
	def get_time( self ):
		return self.player.time
		
	def seek( self, timestamp ):
		self.player.seek( timestamp )
		self.do_action()
		
	def toggle_base_action( self ):
		'''
		Switches the base action from play to pause
		and vice versa
		'''
		self.set_base_action( self.PLAY if self.actions[0] == self.PAUSE else self.PAUSE )
		
		
	def set_base_action( self, action ):
		'''
		The bottom element of the action stack is the base action.
		This one can be switched from play to pause, rather than having those elements added on the stack.
		I think this is a better representation of the use of the player - its doing it base action
		and then a user brings up a dialog or begins to seek the video, so it pauses till they are done.
		Explicitly pushing a play action could get mixed up if popped in the wrong order.
		'''
		self.actions[0] = action
		
		# If we ask the player to play, and the handle is already at the end of the video,
		# Seek to the beginning of the video
		if action == self.PLAY and self.get_time() == self.get_duration():
			self.seek( 0 )
		
		self.do_action()
		
	def start_action( self, action ):
		self.actions.append( action )
		self.do_action()
		
	def end_action( self ):
		self.actions.pop()
		self.do_action()
		
	def do_action( self ):
		'''
		Reads the end of the action stack
		And does that action
		Call this everytime you touch the action stack
		'''
		
		if self.actions:
			if self.actions[-1] == self.PLAY:
				self.player.play()
				return
		self.player.pause()
			
		
	def draw( self ):
	
		self.player.get_texture().blit( self.x,self.y, width = self.WIDTH, height = self.HEIGHT)
		if self.actions[-1] == self.PAUSE:
			self.play_button.draw()
		
	def mouse_press( self, x, y, button, modifiers ):
		
		self.toggle_base_action()
		
	def key_press( self, symbol, modifiers ):
		
		if symbol == key.SPACE:
			self.toggle_base_action()	